{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 8.回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from numpy import *\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 8.1.读取数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def loadDataSet(fileName): \n",
    "    \"\"\"\n",
    "    读取数据\n",
    "    参数：\n",
    "        fileName -- 文件名\n",
    "    返回：\n",
    "        dataMat -- 数据矩阵\n",
    "        labelMat -- 标签矩阵\n",
    "    \"\"\"\n",
    "    # 特征数\n",
    "    numFeat = len(open(fileName).readline().split('\\t')) - 1\n",
    "    dataMat = []; labelMat = []\n",
    "    fr = open(fileName)\n",
    "    for line in fr.readlines():\n",
    "        lineArr =[]\n",
    "        # 以制表符分割\n",
    "        curLine = line.strip().split('\\t')\n",
    "        for i in range(numFeat):\n",
    "            lineArr.append(float(curLine[i]))\n",
    "        dataMat.append(lineArr)\n",
    "        labelMat.append(float(curLine[-1]))\n",
    "    return dataMat,labelMat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def standRegres(xArr,yArr):\n",
    "    \"\"\"\n",
    "    标准回归函数\n",
    "    参数：\n",
    "        xArr -- x参数\n",
    "        yArr -- y参数\n",
    "    \"\"\"\n",
    "    # 转换为矩阵\n",
    "    xMat = mat(xArr); yMat = mat(yArr).T\n",
    "    xTx = xMat.T*xMat\n",
    "    # 如果行列式为0，则为奇异矩阵\n",
    "    if linalg.det(xTx) == 0.0:\n",
    "        print(\"奇异矩阵，没法求逆\")\n",
    "        return\n",
    "    # 公式法计算\n",
    "    ws = xTx.I * (xMat.T*yMat)\n",
    "    return ws"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "结果ws = [[3.00774324]\n",
      " [1.69532264]]\n"
     ]
    }
   ],
   "source": [
    "xArr,yArr = loadDataSet(\"ex0.txt\")\n",
    "ws = standRegres(xArr,yArr)\n",
    "print(f\"结果ws = {ws}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "预测并绘图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x26c60c81358>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAD8CAYAAACb4nSYAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3Xl8lNX1+PHPSTIkE7awCiSEsIYtLBLUFlFRf2LVIu74LXVBpa5VW7HY2opaK5a6V6soWlutG2pEraW1YFUsSEJA1kBYRBLKHrZMQpI5vz9mJk4mM5lJMklIct6vFy8y89x55j4sZ+6ce557RVUxxhjTOsQ0dQeMMcY0Hgv6xhjTiljQN8aYVsSCvjHGtCIW9I0xphWxoG+MMa2IBX1jjGlFLOgbY0wrYkHfGGNakbim7kCgrl27alpaWlN3wxhjmpWcnJy9qtotXLuIg76IxALZQIGqXhBw7HFggvdhItBdVZO8xyqA1d5j21V1Uk3vk5aWRnZ2dqTdMsYYA4jIN5G0q81I/3ZgPdAh8ICq3un3xrcBo/0Ou1R1VC3exxhjTAOJKKcvIinA+cCLETS/Eni9Pp0yxhjTMCKdyH0CuBtw19RIRPoAfYFFfk8niEi2iCwVkcl166YxxphoCJveEZELgN2qmiMiZ4RpPgWYr6oVfs+lqmqhiPQDFonIalXdHPAe04HpAKmpqdVOWlZWxo4dOygpKQnXXVMLCQkJpKSk4HA4mrorxphGEklOfxwwSUTOAxKADiLyqqpODdJ2CnCL/xOqWuj9fYuIfIon3785oM1cYC5AZmZmtQX+d+zYQfv27UlLS0NEIuiyCUdV2bdvHzt27KBv375N3R1jTCMJm95R1XtUNUVV0/AE9UXBAr6IpAOdgP/6PddJROK9P3fF8wGyrradLCkpoUuXLhbwo0hE6NKli317MqaVqXOdvog8AGSr6gLvU1cCb2jVrbiGAM+LiBvPB8xsVa110Pe+X127akKwP1NjWp9aBX1V/RT41PvzbwKOzQrS/ksgo869M8aYJpSVW8CchXkUFrnoleRkxsR0Jo9Obupu1Ystw9BE2rVrB0BhYSGXXnppjW2feOIJiouLKx+fd955FBUVNWj/jGntsnILuOfd1RQUuVCgoMjFPe+uJiu3IGrvUVFRzN69C8I3jCIL+lFUUVERvlGAXr16MX/+/BrbBAb9v//97yQlJdX6vYwxkZuzMA9XWdX/066yCuYszIvK+YuK/sPy5SNYs+ZiXK6tUTlnJCzoR2jbtm0MHjyYq6++mhEjRnDppZdSXFxMWloaDzzwAKeeeipvv/02mzdv5txzz2XMmDGMHz+eDRs2ALB161a+973vMXbsWH79619XOe/w4cMBz4fGXXfdRUZGBiNGjODpp5/mqaeeorCwkAkTJjBhgmeli7S0NPbu3QvAY489xvDhwxk+fDhPPPFE5TmHDBnCDTfcwLBhwzjnnHNwuVyN+cdlTLNXWBT8/0yo5yNVXn6YjRtvYeXKMwBl5Mh/4XQ2XgXdcbfgWjibNt3BkSMro3rOdu1GMXDgE2Hb5eXlMW/ePMaNG8e0adN49tlnAU+9+xdffAHAWWedxXPPPcfAgQNZtmwZN998M4sWLeL222/npptu4qqrruKZZ54Jev65c+eydetWcnNziYuLY//+/XTu3JnHHnuMxYsX07Vr1yrtc3JyePnll1m2bBmqysknn8zpp59Op06d2LRpE6+//jovvPACl19+Oe+88w5TpwarsjXGBNMryUlBkADfK8kZ0euDzQec1mcdeXk3UFq6nZSUO+jb97fExraNdtdr1OyCflPq3bs348aNA2Dq1Kk89dRTAFxxxRUAHDlyhC+//JLLLrus8jWlpaUALFmyhHfeeQeAH//4x/ziF7+odv5PPvmEG2+8kbg4z19L586da+zPF198wUUXXUTbtp5/NBdffDGff/45kyZNom/fvowa5VnyaMyYMWzbtq2ul21MqxAYpNO6OCn05vN9nI5YZkxMj+hc97y7ujI9dODIHtau+z1JBxfidKYzevQXdOz4/Qa6kpo1u6AfyYi8oQSWOPoe+4Ku2+0mKSmJlSuDfxMJVyKpqrUqo6xaHVtVfHx85c+xsbGW3jGtUqTVN4FBuqDIVW2UL8AlY5JDvt7/fY6Wlleea2S3r7h62DMkxR/gPwVTuHfKy3zw9T7mLFzUJFVBltOvhe3bt/Pf/3ruPXv99dc59dRTqxzv0KEDffv25e233wY8QXnVqlUAjBs3jjfeeAOA1157Lej5zznnHJ577jnKy8sB2L9/PwDt27fn8OHD1dqfdtppZGVlUVxczNGjR3nvvfcYP358FK7UmOYvXPVNVm4B42Yvou/Mj/j5W6uqTdoGUuDVpdsZN3tRlXMM+80/uOPNlVXep8hVRlvHIaZnPMqdYx7gaFk7HvzvH3h59VQ++Hpfg1cF1cSCfi0MGTKEV155hREjRrB//35uuummam1ee+015s2bx8iRIxk2bBjvv/8+AE8++STPPPMMY8eO5eDBg0HPf/3115OamsqIESMYOXIkf/vb3wCYPn06P/jBDyoncn1OPPFErrnmGk466SROPvlkrr/+ekaPHh3s1Ma0OjVV3wR+IFTU8K05kC9I35u1mhnzV3H0WPUPi8wTlvC7U2/mpJ6fkZV/JbO+fIKthwYhwKwFaxu0KigcqSlF0BQyMzM1cBOV9evXM2TIkCbqkce2bdu44IILWLNmTZP2I9qOhz9bYxpC35kfESq6dUp0cKC4rF7njxWp9mHRvk0RVw39E2N7LGHbwf7MW3M73x7uF9H5BNg6+/w690dEclQ1M1y7ZpfTN8aYSISqvgHqHfAh8NuBckrP//CjIXNJiCvm7Y1X8Y+tF1OhkYfYSKuC6suCfoTS0tJa3CjfmJZsxsT0KpOzDSUpfh9XD3uG0d2/Ir8onXmr7+B/R3uTVItvE45YiagqKBos6BtjWiRfNcwdb0b3vp7vKKcmf8L/DX6RuJgyXt9wHf/cNgkllqmnpJLZp3O1Dx2BoCmntm3iGq16x4K+MaZFCxVoa+J0xCIoxWXBNwvsnLCba4c/TUbXXDbsH87La25jV3EyiY4Y2sTF8trS7SzesIdLxiSzeMOeytLMUOmmg676p5siZUHfGNNizVmYF3HAjxXBrVpZNw8w4+1VlLm/O0ObGOX/9f0nF/R9EUH567obWbT9PJQYOiU6KClzU+QN4AVFLt7JKeDhizMqR/HjZi+q112+0WBB3xjTYtVmnZxHLx8ZNMXiu+lq+AkH+Gnmszgq/sv6faOZt+ZW9rpOADzfDFQJWYo5eXQy92atpvBg9f5EepdvtFjQr6NZs2bRrl077rrrrqDHs7KyGDRoEEOHDm3knhljfCKdTO2U6Aga8CePTubCUT3YseNptm79JYKDAekvUrRzIvGbNiIuF0mJDlSpHOEHKixycW/Wal5dur3asURHDL/z+ybQGOzmrAaSlZXFunV12iTMGBMlkdyG5HTEct8PhwU9dvToBnJzT2Pz5jtJSprA2LFr6dnzOiafmMKSmWfy+BWjqqR0gunodPDasuoBH6C4zM2db66scpdvQ2uRQd//9upo/mE+9NBDpKenc/bZZ5OX57l77oUXXmDs2LGMHDmSSy65hOLiYr788ksWLFjAjBkzGDVqFJs3bw7azhjTsGqaIBUgOclZJefu43aXs337I2Rnj6K4eD2DB/+VjIwPSUhIqdIu2F2/1d5Hav7waeylGFpc0G+o3W5ycnJ44403yM3N5d1332X58uWAZ2XL5cuXs2rVKoYMGcK8efP4/ve/z6RJk5gzZw4rV66kf//+QdsZYxpWqAnS5CQnW2efz5KZZ1YL+EeOrGbFilPYsmUmXbqcz9ix6+jRY2rQxRAjmTOItFa/sZZiaHFBv6F2u/n888+56KKLSExMpEOHDkyaNAmANWvWMH78eDIyMnjttddYu3Zt0NdH2s4YEz0zJqbjdMRWeS7UxKnbfYxt2x4gJ2cMpaXbGTr0LYYNm098fI+Q54921U2oks5oanFBv6F2u4HgSyNfc801/PGPf2T16tXcd999lJSUBH1tpO2MMdEzeXQyD1+cQXKSs8Z0zuHDOeTkjGXbtvvo1u1Sxo5dR/ful4Vd6jzYh0p9xNZiafW6ijjoi0isiOSKyIdBjl0jIntEZKX31/V+x64WkU3eX1dHq+OhhPrkre8n8mmnncZ7772Hy+Xi8OHDfPDBBwAcPnyYnj17UlZWVmXJ5MDlkEO1M8Y0rMmjk1ky88yg6ZyKihK2bPklOTknU1a2h+HDsxg69G+0adO1hjNWPbf/h0qS01Fje1+7UGqz2mdd1aZk83ZgPdAhxPE3VfVW/ydEpDNwH5CJZ74iR0QWqOqBunQ2EsHW24hGHeyJJ57IFVdcwahRo+jTp0/luvUPPvggJ598Mn369CEjI6My0E+ZMoUbbriBp556ivnz54dsZ4xpGgcPLiUvbxrFxevp0eNa+vd/FIejU63PM3l01Y1VQt2AlZzkZMnMM8O2aWgRLa0sIinAK8BDwM9U9YKA49cAmUGC/pXAGar6E+/j54FPVfX1UO8VjaWVI90tx9jSyqb1qagoZuvWX7Njx+PEx6eQnv4CnTtPjNr5A3fhAs/A0z+tFEmb2or20spPAHcD7Wtoc4mInAZsBO5U1W+BZOBbvzY7vM81qMBPXmNM6xBuwFdU9Bl5edfhcuXTq9dN9Os3m7i4UMmLuvG9X039iKRNQwkb9EXkAmC3quaIyBkhmn0AvK6qpSJyI55vBWdC0PRVta8WIjIdmA6QmpoaYdeNMeY7wfa5vefd1QBckNGRLVtmUlj4DAkJ/Rg5chGdOk2o6XT1EsnAs6kGp5FM5I4DJonINuAN4EwRedW/garuU9VS78MXgDHen3cAvf2apgCFgW+gqnNVNVNVM7t16xa0E8fbDl8tgf2ZmpYkVLn2u//9G8uXD6ew8FlSUu5g7NivGzTgH+/CBn1VvUdVU1Q1DZgCLFLVqf5tRKSn38NJeCZ8ARYC54hIJxHpBJzjfa5WEhIS2LdvnwWpKFJV9u3bR0JCQlN3xZh68d2BHzgx6ow7yrXDnmLa0LuJiYln9OjPGTDgcWJj2zZRT48PdV5wTUQeALJVdQHwUxGZBJQD+4FrAFR1v4g8CCz3vuwBVd1f2/dKSUlhx44d7Nmzp67dNUEkJCSQkpISvqExx6lgE6IAI7st5+phfyQp/gD/KZjCvVNeIja28ZYvPp41i43RjTEmmMARflvHIX40+AW+n7yYbw/34bX1d3Lj/7u0VRR22MboxpgWz/9O+zEnfMlVQ5+lreMwWflXsmLfVfzsnMZdtrg5sKBvjGm2eiU5OVS8kx8PeY6Ten7BtoP9+UP2A7hjh1XeCGWqsqBvjGmWVJVfTliHHvwV8XHFzN94FR9vvRi3xvGjU4JXARoL+saYZqi0tJCNG2+irWsBB2MymLXkJgqOfnePzzs5BWT26WypnSBa3CqbxpiWS1XZufNlvvpqKAcO/JP+/R9lTvajVQI+NN7a9M2RjfSNMc1CScl28vKmc+DAQjp2PI309BdJTBxIQdFHQdtHYzn1lsiCvjHmuKbqprBwLlu2zEBVGTjwjyzfNYlbn9pEYdFGYkSCLkkc7Q1OWgoL+saY45bLtZm8vBsoKlpMp05nM2jQCyzc4OCe9767IStYwI/GcuotlQV9Y8xxR7WCgoI/sin/HkrLY3h9w23kH7mQGW5HyM3IY0Vwq9py6mFY0DfGHFeOHt1AXt51HDr0JWv2juWl1bdwoLQrUBJ0yQUftypbZ5/fuJ1thizoG2OOC253OTt2PMrWrfcRG5vI2/kz+Sh/HP4rtLvKKoi1HH69WMmmMabJHTmymtzc77Fly0y6dDmPsWPX8ff8Uwm2JUeFarXNyC2HHzkL+saYJuN2l7Ft2wPk5IyhpOQbhg59i2HD3iE+vkfIkXtykrPKZuS+x5bDj4yld4wxTeLw4RVs2DCNo0dX0b37lQwY8CRt2ny3fMKMielB95H1TdJakK8bC/rGGCD8/rLRUlFRwjffPMj27Y/Qpk13hg/PomvXC6u1a8p9ZFsyC/rGmBr3l41mkD14cCl5edMoLl5Pjx7X0r//ozgcnUK2txF99FnQN8aE3F92zsK8yqBbn28CFRXFbN36G3bseJz4+GRGjPgHnTtPjPp1mPAs6BvTymXlFlTbX9bHt35NsG8CM+avYtaCtRx0ldErycmEwd1YvGFPtQ+FoqLPyMu7Dpcrn169bqRfv0eIi+vQaNdnqrKgb0wr5gvmoSQlOoDg3wTKKpQiVxng+RB4den2ymMFRS5mvf8VTtf7xB97hYSEfowcuYhOnSZE3C/L5TcMC/rGtBLBAmmoJQ18DhaXkZVbUOsVK4d2Wcm04U/hKN1Dcsrt9Ov3ELGxbSPuZ2PML7RWEW+MLiKxQDZQoKoXBBz7GXA9UA7sAaap6jfeYxWAbyixXVUn1fQ+tjG6MdEXGEjBU/5YU8D3SfbWy4dKAflzxh1lSvo8Tu/9T3YeTeal1bfzr5kzqvWlplF84Gbn/v2wLRBDa4iN0W8H1gPBknG5QKaqFovITcDvgSu8x1yqOqoW72OMibJQE7WhljTwV1jk4vErRtW47g3AyG7LuXrYH0mKP8BHWy4hK///aJfQrkqbSEbxob5V2Pr40RHRHbkikgKcD7wY7LiqLlbVYu/DpUBKdLpnjImGUAGzQhVHTPWlDvz1SnIyeXRylbtgOyU6Kl/X1nGYGzIe5c4x91Nc1pYH//sH3t54LWXueI6UlJOVW1B5rpqqhPzfL1Q/TP1FOtJ/ArgbaB9B2+uAj/0eJ4hINp7Uz2xVzapdF40x9dXR6aicdK1GwOmIwVXmDnp4wmDPXbKBN0slJTro1/4/XDX0Wdo6DpOVfyUfbr6ccnVUvrbMrZUBfc7CvJApooIiF31nflRZBfROTkHQO3FN/YUN+iJyAbBbVXNE5IwwbacCmcDpfk+nqmqhiPQDFonIalXdHPC66cB0gNTUqntdGmPq71h56LRMWYXSvX0CxcfKOVBc/YPh9WXfktmnM0BlaqZ9myKmDHyek3t+zraD/Xk0+wG2H+4X9Py+FE64+QP1tn0np4BLxiQHLf809Rd2IldEHgZ+jGeknoAnp/+uqk4NaHc28DRwuqruDnGuPwMfqur8UO9nE7nGRF/azOD7yPr4EjyhooHTEUuCI4YDxcc4uednTB3yPAlxxbyf/398vPViKjT0+DGSeYNANmlbe1GbyFXVe4B7vCc9A7grSMAfDTwPnOsf8EWkE1CsqqUi0hUYh2eS1xjTCHyVMuH0ClOh4yqrID5mNz8d/SdOPGEpm4vSmbf6dgqP1vzNPNIKoUA2adtw6lynLyIPANmqugCYA7QD3hYR+K40cwjwvIi48Uwaz1bVdfXvtjEmnGBlmsEIVObLg7dXTk3+N1cOfgFHTBlvbJjGwm0XosRWO5f/Of3vBYik3NOfTdo2nFoFfVX9FPjU+/Nv/J4/O0T7L4GMunfPGFNX4W688vnRKalV8uU/f2tVZTqmc8Jurh32RzK6rWBz0XBeWXcH2w/1qPF8wVIzkXz4+NikbcOyO3KNaaHCpUjatonloYuqbj7i+/mX767i5B4fcXn6ywjKG3k3c+7YmfysT0yVD4VA/t8aAs85a8Ha0BVEXsk2advgLOgb0wL518aHkpTYJmhwnTi4lLbnPISj4kvW7h3F37+dwQ1nnF6l7Yz5qyirqB74A781+CstD14SCp7Rve1+1Tgs6BvTwmTlFjDj7VUhK3F8Ar8JqFZQUPBHtmz5JQkSR/9BL3D66ddxi1S9ecsXmO//YG1liWeS08GsScNCBu2aUk02um9cFvSNaWHmLMyjzB2+RNJ/srS4OI8NG6Zx6NCXdO58HoMGPU9CQugb62u7uUmoVJOAlWY2Mgv6xrQwkZQ7+iZL3e5ydux4jK1bf0NsbCKDB/+FE06YikjNSzPUVq8kZ9AKHqvSaXwRrb1jjGk+wgXS5CQnD1+cwdkDD5Cb+z22bPkFXbqcx9ix6+jR48dRD/jgmdx1OqqWeFqVTtOwoG9MCzNjYnrQRdQcscITV4zi87vHM6rTS+TknEhJyTcMHfomw4a9Q3x8zaWY9RG4YJvvg8fy+I3P0jvGtDDBSiQ7JTq474fDOGvALnJyzufo0VV0734lAwY8SZs23RqtXxbkm54FfWNaGN/SCwddZZWVMZNGdmXbtgfJyZlNmzbdGT48i65dL2zqrpomYEHfmBYk2CYlz3/yNu0PP0usexM9elxD//6P4XB0auKemqZiQd+YFsS/Hr5NTAkXDXyNiWnvc8jVlfGZH9Oly7lN3EPT1CzoG9MC+FI6vrLIQZ3WMG34k/Rou5NF23/A23nXsn6iBXxjQd+YZs8/pRMf6+KyQa9wdp8P2V18Ao989RDr94+s3NzcGAv6xjRzvpTO0C4ruXbY03Rx7uaf2yYxf9NVHKtIsHp4U4UFfWOauQNH9nLNsJc4o/dCdh5N5nfLHiG/aChg69qY6izoG9OM7dv3EQ+Pv4X2bfbz0ZZLyMr/P8rc8YBtOWiCs6BvTDNUVraf/Pw72LXrr7RzpvP7pfeyYf+AyuOW0jGhWNA3ppnZs+c9Nm68ifLyffTp8xv69Pklh9vvZc7CPAqLXJXbFFpKxwRjQd+YZuLYsd1s2nQbe/a8Rbt2oxkx4h+0bz8KsCUOTOQs6BtznFNVdu9+k/z82zhWdoh/bZ/GW+sncULH/cyYWGDB3tSKBX1jjmOlpTvZuPEm9u17n/LYUfxu6Y1sKfJsblJQ5OKed1cDWOA3EYt4aWURiRWRXBH5MMixeBF5U0TyRWSZiKT5HbvH+3yeiEyMTreNadlUlZ07/8zy5UM5cGAh/fv/gVlLfl8Z8H1cZRXMWZjXRL00zVFtRvq3A+uBDkGOXQccUNUBIjIFeAS4QkSGAlOAYUAv4BMRGaSqwTfLNKYJ+ZYyaOrJ0JKS7Wzc+BP27/8HHTuOJz19HomJAyko+iho+2A7UhkTSkQjfRFJAc4HXgzR5ELgFe/P84GzxLP9zoXAG6paqqpbgXzgpPp12Zjo8y1lUFDkQvkudZKVW9BofVB1U1j4PMuXD6eo6HMGDHiaUaM+JTFxIABJiY6Qr23MfprmLdL0zhPA3YA7xPFk4FsAVS0HDgJd/J/32uF9zpjjiv/qlD6NmTpxubawatXZbNx4I+3bn8TYsatJSbkVke/+i2oNe51bisdEKmx6R0QuAHarao6InBGqWZDntIbnA99jOjAdIDU1NVyXjIm6UJuJ+z/fEOkfVTcFBX9ky5Z7EIlj0KAX6NnzuqD71B707oJVm/4bEyiSnP44YJKInAckAB1E5FVVnerXZgfQG9ghInFAR2C/3/M+KUBh4Buo6lxgLkBmZmYN4xljGkavJGfQ3Lhvk/Fgm5PUt3KmuDiPDRuu49ChJXTufB6DBj1HQkLvKm2ycgu4/4O1HCgOHfD9+2lMOGHTO6p6j6qmqGoanknZRQEBH2ABcLX350u9bdT7/BRvdU9fYCDwVdR6b0yUTBjcrdrXUv+lDEKlf2YtWMu42YvoO/Mjxs1eFFFu3e0uZ/v2OWRnj6K4eB2DB/+FjIwPgwb8GfNXhQ34gC25YCJW5zp9EXkAyFbVBcA84K8iko9nhD8FQFXXishbwDqgHLjFKnfM8SYrt4B3cgqq5B0FODG1I3MW5nHnmyur5yS9ilxllZuPRzL6P3JkDXl50zh8eDldu17EwIHPEh/fI2jbOQvzKKuI7Iuv1embSNUq6Kvqp8Cn3p9/4/d8CXBZiNc8BDxU5x4a08CCjeIV+HLz/pDBPhTf5G9gEHa7y9i+fTbffPMgcXEdGTr0Tbp1uyxo7t4n0jy9bZBiasPuyDWtXqjgWtfJpcDzHT6cy4YN13L06Cq6d7+SAQOepE2bbmHPk5ToCJvasdU0TW1Z0DetXqhJ3FDE+5qi4mMcPVY9W+mrp3e7S9m27UG2b59NmzbdGD48i65dL4z4fWoq0QTbIMXUjQV90+rNmJhepTKnJv4bk4y6/59A9deowqFDy9iwYRrFxevo0eMa+vd/DIejExC89BOo3Ng8VoSKMBF/2+zza3mVxnhY0DetUmDgvWRMMos37KGwyEVHp4NDJWW4g8Td4mPlZOV6VrYMVjfviCnl3NR5rFjxPvHxvcjI+JguXc6t8r6BpZ8z5q8ChTLvG4YL+JbDN/UR8YJrxrQUwZZceG3pdiYM7sbW2ecjQtCAD3CguKxyeYbA2vhBndbw4LjbOLfve3y16zymffgYk15oU6WMM9ikcVmFVgb8cCyHb+rLRvqm1QlVrfPa0u1k9ukcdvLUV6HjSwu53Ue4bNArnN3nQ/YUn8Cj2b9j9d4RQPUyzrreOeubR7AcvqkvC/qm1ampWifSNWwKi1xMHp1MXPkXHNt3B0nxu/jkm0m8vfHHlFZU/QbgX8ZZ20ljsA3OTXRZese0OjUtWVBY5CLJGXo1S5++XSrIy5tOu6NTiHfEM3vZbF5dP71awPc/L3gmjZ2O2CrHHLGCIyZ4vb6lc0y0WdA3rUJWbkHlcglHS8tDtuuV5GTWpGEhgzBAZo8c7j3pRnbunEdJm5u489+PsbFoWI3v7/ugmTw6mUvGJBPrvSkrVoQrxvZmzmUjKydo/Y/5viXY0skmWiy9Y1q8wIqZIlcZMVRfJ9w3qvblzH3VPR2dDkSgrGw/00a8xInd/kWicxiDB7/PD549zDF3+HTNzoMu0mZ+RJLTwdFj5ZUVOhWqvJNTQGafzpUpnIZY3M0YHwv6pkXLyi3g52+tqlYG6QaSnA7axscFXSp58ujkKgF2z5732LjxDsrL95Ga+mv69PkVMTHxFIbYzSqQrzinKEiZZ+DSDTWt7W9B39SXBX3TYvlGzKHq3otcZRx0ldVYFXPs2B42bbqVPXveol270YwY8Q/atx9VebwuE7PB+E8uR7K2vzF1ZTl902IFGzEHCrU1oqqya9cbLF8+lL17s+jb97eceOKyKgEfgk/Mhp4NCM1/cjnURLOtmW+FhZETAAAcBklEQVSiwYK+aRH8J2p969rXZmTsvzViaelO1qy5iPXrryQhoR+ZmSu86ZzqVT2TRyfz8MUZJCc5ETzllY9fMapWd80GVugE+yCxKh4TLaLhVnVqZJmZmZqdnd3U3TDNSODEJ3iCZIIjJqINSHwE5b937CM//w7c7hLS0h6kd+87EYkN/+IgfappHf5OiQ6KikOnlhpia0bTsolIjqpmhm1nQd80d+NmLwqaV09yOigtd1f7MIiPi6k2odo5YTc3jvoTg5KW07HjqaSnzyMxcVC9+pU2M/Qkry2YZqIt0qBvE7mm2QuVxilylTH1lNTKhdT8V7T87puBckbvf3BF+kskxAkDBjxNcvLNiNQ/8xlqtczYGjZOMaahWdA3zV5NFTTv5BTw8MUZQVMjL366mPNS5zC0y9eUxY7jlMy/4nT2jVq/QlUNhVtF05iGZBO5ptkLNvHp4z9B66PqJrPbO9w95idkdN/KoEFzOfvUz6Ma8CH0Esi2NLJpShb0TbPnq6AJxT/9U1y8kdzc08jPv52kpNMZO3YtvXrdUONetXVlVTjmeGRB37QIk0cnhxxBKzB+9r/4eOm9ZGePpLh4HYMH/4WMjI9ISOjdoH0KLOcMlWoyprGEzemLSALwGRDvbT9fVe8LaPM4MMH7MBHorqpJ3mMVwGrvse2qOilKfTemilDbHia328a1g5/EWbKJkriJnD72ZeLjezZKnwKXczCmqUUykVsKnKmqR0TEAXwhIh+r6lJfA1W90/eziNwGjPZ7vUtVq97GaEyUZeUWcP8Ha6sE/Fgp57y+87lwwBsUlyfyzMpfUFjy/1hyauMEfGOOR2GDvnoK+Y94Hzq8v2oqP7gSuK+G48ZEVVZuATPmr6Ks4rt/lqntN3NdxpP06bCFpTtP47V1P+FwWUeEkibsqTFNL6KSTfHckpgDDACeUdVlIdr1AfoCi/yeThCRbKAcmK2qWUFeNx2YDpCamlqrCzBmzsK8yoAfJ2VMGvAG5/d9m8PHOvLUil+xYvf3Ktva+jWmtYso6KtqBTBKRJKA90RkuKquCdJ0Cp6cv39SNVVVC0WkH7BIRFar6uaA888F5oLnjtw6XYlptXw1+v065nHd8CdJbr+dLwrO4m/rb6C4vF1lO6ucMaaWN2epapGIfAqcC4QK+rcEvKbQ+/sW72tHA5urv9SYukmIPcaFA15lYloWB0o682j2LFbv9dyNHiuCW9XWrzHGK5LqnW5AmTfgO4GzgUeCtEsHOgH/9XuuE1CsqqUi0hUYB/w+Wp03rVtWbgFvfTmfWd//PT3aFrJ4+7m8mTeNkorEyjaPXj7SAr0xfiIZ6fcEXvHm9WOAt1T1QxF5AMhW1QXedlcCb2jVFdyGAM+LiNv72tmqui6K/TetVNaKjeSuncH1Qz9gr6s7j3z1W9bvr1ok1inRYQHfmACRVO98TdUSTN/zvwl4PCtImy+B0LdKGlMHBw78G/fuqZyesotPvrmAdzZdRWlF1QlapyOW+35Y82blxrRGtuCaaTbKyw+yefPd7Nw5l9KKZB5eNptNRdUDe7Ll740JyYK+aRb27fuYjRunU1JayD+3Xcr8jVdS5o6v1i45ycmSmWc2QQ+NaR4s6JvjWlnZfvLz72TXrr+QmDiM51bfw7KCPkHbWkmmMeFZ0DfHrT17sti06SZKj+1l8Y6pvL72Esq0+j61PraYmTHhWdA3x51jx/awadNt7NnzJuUxw3hk2b1sOpBW42uSk5wW8I2JgAV9E1Jjb86tquze/Sb5+bdRXn6Ivn1/y9Q3xvLtgZo3N7e0jjGRs6BvqvAF+oIiF8J3K+sVFLm4513PCtkNEfhLS3eyadPN7N2bRfv2JzF48Eu0bTuMbw+E3lxcwO60NaaWLOibSlm5BVXWow9cBMm39WA0A6yqsmvXX8jPvwO3u4R+/eaQknIHMTFxZOUWVPng8WdVOsbUjQV9U2nOwrxqG5AEKgyxAXldlJR8y8aNP2H//o/p2PFU0tPnkZg4qEp/ggV8AUvnGFNHFvRNpUgCejSWJlZVdu58gc2b70LVzYABT5OcfDMiVXfvDNUfpWFSTMa0Bhb0TaVeSc7KZYqD8Z8wreskr8u1hby8GygqWkRS0pmkp7+I09m3Vv0JtReuMSY8C/qtVLCgPWFwN15duj1o+xiB+LgY7nxzJfd/sJYjJeWUuT3Jl0gmeVXdFBQ8w5YtMxGJZdCgufTseT0iErKPMyamV9sRyxErltoxph4s6LdCgRO2BUUuZsxfVeMmmG6FIpendPJAcfUSypomeYuLN5KXdx0HD35B584/YNCg50lI6B1ZZwP7ZFvsGFMvFvRboWATtv6j6boKzMGrVvDtt4+xecuvKSl38Oq6O9lWfD4TthSxeMOmoKmhrNwCZi1YW/kBE6jMrVGvIDKmNbGg3wpFswLHn/8k74LsRRz83y30breBFbtO4S/rbuZgaWegpEoKyT81BDDj7VWVaaNQGqr/xrQGFvRboXATtoESHTEUl7lrbOOI8eTa3e4yFi77FYmux6FNIs+uvJuv/jceT6FlcL7UEBA24Pv6b4ypGwv6rdCMielVcvrR0C4hjrMG7GbFigtwlq5k6a7TeG3dTzhc1jGi10c6erclF4ypHwv6rdDk0clkf7M/ZKVOoHCj/DgpY0Kvv7JixTs4HF15asWvWLH7e7Xqk2/0Hu4biK2kaUz9xIRvYlqae7NW81qEAT+cvh3zuP/7tzNpwJt07/4jxo5dy65jtVsewTd6nzC4W43tbCVNY+rPgn4rk5VbwGtLt0dc+eh0xJLkrL6GvSOmlMsHvcSvT5mB01HMkcS/MGTIn3E4OjNhcLdqGXzf4+QkJ+P6dybWW58fK8IlYzyB/J2cghr7YWkdY+ovbHpHRBKAz4B4b/v5qnpfQJtrgDmA73/tH1X1Re+xq4F7vc//VlVfiU7XTV2EWs/GZ+opqSzesKdKOSVQZQ5gYNJarst4kh5tC1lSeB4fbL2eXYfb8PCiRUwY3I13cgqqvYfTEcPvLh4BeCp0KtTTokKVN7/6lg9X7Qw5x2B73hoTPaJa85hPPLdMtlXVIyLiAL4AblfVpX5trgEyVfXWgNd2BrKBTDy31eQAY1T1QKj3y8zM1Ozs7Dpejgmn78yPQgZ938qVwe7WBXjyXyv5/gnPc1bqh2hMCq7EOcxY0LFKsA61KiZ4RuuguMLMEfgTYOvs8yNub0xrJSI5qpoZrl3Ykb56PhWOeB86vL8izQ5MBP6lqvu9nfoXcC7weoSvN/UUGMCdNZRfzpiYHvRu3XveXc2cSYd4+LSZlJRsIzn5Nvr2fYjT//AVrrKAG7Jq6EtdqoWsPNOY6IqoekdEYvGM0gcAz6jqsiDNLhGR04CNwJ2q+i2QDHzr12aH9znTCIIF8HAC79Z1xh3l8kEv0+7oPxDnQEaN+oykpFOBhr9JyvL4xkRfRBO5qlqhqqOAFOAkERke0OQDIE1VRwCfAL68fbA7cqoNBkVkuohki0j2nj17Iu+9CSkrt4Cfv7WqVqNr3zcCn4yu2fx23C2cnvJP/r7lYjIzV1UGfKjbKDwm9D1alQRPqsnKM42JvlpV76hqEfApnhSN//P7VLXU+/AFYIz35x2A/8paKUBhkPPOVdVMVc3s1q3msj0Tnm+EXxFmviaQLwXU1nGY6zMe5+eZs3CVJ/Lg0jks2X0LsbFVg/yMienePP13Ah8H+r+TU3HEho78yUlOts4+nyUzz7SAb0wDCBv0RaSbiCR5f3YCZwMbAtr09Hs4CVjv/XkhcI6IdBKRTsA53udMA4pkB6xgeiU5+eWZW/ndqTfzvZ6LWZB/BbO+fJL/FQ8NmmaZPDqZhy/OIDnJWWV0Hmq1ZAF+OzmDOZeOpFNi9TJQS+cY0/Aiyen3BF7x5vVjgLdU9UMReQDIVtUFwE9FZBJQDuwHrgFQ1f0i8iCw3HuuB3yTuqbh1CXX3i3xMPeNf4E2xe9T7hzGn1Y+TE5hStgNUiaPTq52LNTdvj86JbXKa+q6EYsxpu7Clmw2NivZrL9xsxfVYkE15dz+y7h80LPEcpi0tPvo3ftuYmKqj8QjlZVbwM/eXIl/jVAM8NgVoyyoG9NAIi3ZtDtyW6Bwyxn4nND2IHMveIYpA39Lx3b9yczMpU+fX9Ur4IMnvRRYFOr2Pm+MaVq24FoLtHhDuAoo5fwBX3DJwOeIc5eS1m8OKSl3EBMTnX8OodJLtg6+MU3Pgn4LVFNw7dVuP/ef8TKO8sV07HAq6enzSEwcFNX3D7Vev91oZUzTs/ROC5OVW0BM0PIZZULvf/DQqTcT717GgAFPMWrUf6Ie8CF0KadV5hjT9Gyk34KEqs/v6vwf12c8zeDOq0hKOpP09BdwOvs1WD98k7VWmWPM8ceCfgsSWJ8vuDkr9SMuG/Rn2sQ5GDToeXr2vAEJVUgfRcFKOY0xTc+CfguRlVtQJY9+QmIB04Y/SXrndXy9ZwzTf/geCQm9aziDMaY1sKDfAvjSOgBCBRPT3ufiga9S5nbwwtd3sq34fH5qAd8YgwX9FuH+D9biKqugV7tvuG74k/RP2siKXafwyrqbOebuxsMXD27qLhpjjhMW9Ju5rNwCDrlc/LDfO0wa8Dqu8kSeXXk3X/1vPCA8cYWtVGmM+Y4F/Wbu1c8/4jffe4Q+HbawbOd4Xl13I4fLOgK2kbgxpjoL+s2U213KN988xI3Df8eRYx14asUvWbH7+1XaWF28MSaQBf1m6NChr1i+8ipi3Xks3XkWr2+4nqNl7au0SXI6bJRvjKnGgn4zUlHhYtu2+9j+7aMcLOnMy2tmsXpv9UX1nI5YZk0a1gQ9NMYc7yzoNxMHDy5hw4ZpuFwbWb7rfF5efRWu8rbV2iXb3a/GmBpY0D/OVVQcZcuWX1JQ8DQJCX0YOfITrnmkJGhbAZbMPLNxO2iMaVZswbXj2IEDi1i+PIOCgqdITr6VzMzV/Gfb4KC7zYOtYmmMCc9G+seh8vJDbN48g5075+J0DmTUqM9IShoPwJyFXxFsrzPBqnWMMeFZ0D/O7Nv3MRs3Tqe0tJDeve8iLe0BYmO/G8GH2gZRwfL4xpiwLOgfJ8rKDpCffye7dr1CYuJQTjxxPh06nFylTVZuQcjXd0qs3xaHxpjWwYL+cWDv3vfZuPFGjh3bQ58+99Knz73ExMRXa1fTHrPH2f72xpjjVNigLyIJwGdAvLf9fFW9L6DNz4DrgXJgDzBNVb/xHqsAVnubblfVSdHrfvN27Nge8vN/yu7db9Cu3SgyMv5O+/ajK49n5RZU2YgkVGoH4KCrrDG6bIxp5iIZ6ZcCZ6rqERFxAF+IyMequtSvTS6QqarFInIT8HvgCu8xl6qOim63mzdVZc+et9i06VbKyw+SlvYgqam/ICbmuxSNb7lk36YoBUUuBIJO4oJV7hhjIhM26KuqAke8Dx3eXxrQZrHfw6XA1Gh1sLEFjq6jfaNTaen/2LTpZvbufY/27ccyePDLtG1b/e7ZwF2wIHTAd8SIVe4YYyISUU5fRGKBHGAA8IyqLquh+XXAx36PE0QkG0/qZ7aqZgU5/3RgOkBqamqEXY++YKNr3+YkUL89X1WVXbv+Sn7+HbjdLvr1m0NKyh3ExAT/KyisIZXjL8npYNakYVa5Y4yJSERBX1UrgFEikgS8JyLDVXVNYDsRmQpkAqf7PZ2qqoUi0g9YJCKrVXVzwPnnAnMBMjMzm2xKMtjo2lVWwS/f/RpFgn4YhAq2/t8YBnc/ws9OmoujfBEdOoxj8OCXSEwcVGNfwuXwwbPkgt2Ba4ypjVpV76hqkYh8CpwLVAn6InI28CvgdFUt9XtNoff3Ld7XjgaqBP3jRajRdXGZu9pzrrIK5izMqxL0fYH+u/y7cnrKQq5Ifwl3aQXFbR/g9NG/QqTmG6Gzcgs4Wlpe5/4aY0wokVTvdAPKvAHfCZwNPBLQZjTwPHCuqu72e74TUKyqpSLSFRiHZ5L3uBTJ6Nqff9ANTA11cf6Pa4c9zbCuq1i3bwQvr/kpbeL7ct4p1QO+/7eCpEQHR0rKKXOH/8Jjk7fGmNqKZKTfE3jFm9ePAd5S1Q9F5AEgW1UXAHOAdsDbIgLflWYOAZ4XEbf3tbNVdV1DXEh9ZeUWUHws/Ojan3/Q9aWGBDdnpn7EZYNeQRFeXnMr/9kxERDEVf0D5d6s1by2dHvlJO2B4shKL52OWJu8NcbUWiTVO1/jSckEPv8bv5/PDvHaL4GM+nSwofiPrjs6HRw9Vk5ZReTTCYFBt6DIxQmJBUwb/iTpndfx9Z4x/Hntrewv6VbZxvch4Z8GqgtbPtkYU1et8o7cwFRMUYQ3NsWK4FatVr2TtWI756a9y8UDX6XM7eCFr+9kSeGZ4Lcepu9DIvC9a8uWTzbG1EerC/pZuQX8/K1VVNRy3QIBHr18ZLXR9dGjazlceClTBm9gxa5TeGXdzRws7Vyljf/IfNzsRXUO+GB5fGNM/bSaoJ+VW8CsBWsjHtUH6hiw56zbXca33/6ebdseIKlNAs+uvJuv/jceAla7f+KKUVVeV5+KG7sJyxhTX60i6Nc3pQJV17Y5fHgleXnXcuTISo45JnHvv6dw8FiHoK/zlXX68vh1vQnBbsIyxkRDqwj6wW66ChQjnrz70WPB2/VKcuJ2l/LNNw+xffvDxMV14WjiC9z1QUqN5y4sctXrQ0eAxwO+LRhjTF21iu0SI0mpxIrw0EUZTD0ltdp2hE5HLDPPKiY7ewzffPMg3bv/iJNOWsfvFvULG8g7Oh38/K1VdQ74Pzol1QK+MSZqWsVIP5KbrsrcypyFeSyZeSaZfTpXlnOmdorhnvHvk3B0LhXxvcjI+IguXc4DIvswOVRSRgT3WVVjZZnGmIbQKoL+jInpEaVXfEF88uhkJo9O5uDBJWzYMA2XayM9e06nf//fExfXsbJ9JB8mdQn4VpZpjGkorSK9M3l0Mg9fnEFymHJHXzlkRcVRNm26ndzc8ageY+TIT0hPf75KwAfPh4nTERv1/lpZpjGmobSKkT58txpmqBG/7+apAwcWkZd3PSUlW0lOvo2+fX9HXFy7Gs9Zn7trA1lZpjGmIbWKkb5PqCqeWBEeviiNIYkPsmrVWYjEMWrUZwwc+FTIgO8zeXQyS2aeGZWNyZOcDuZcVv0GMGOMiZYWOdIPtftVqInXoV2yOaH0RnYeKqB377tIS7uf2NjEWr3nfT8cxoz5q2q1fo+P0xHLwxdnWLA3xjS4Fhf0A1et9N/wJHDiNTHuCFcOfpHxKZ8QGzuUE0/8kg4dTq7T+/qnenxLJIdaMTPJ6aBtfFyDbclojDGhiNZyDZqGlpmZqdnZ2XV6bVZuAXe+uTLoXa++EkhfTn9096VcPfQZ2rc5SJnzNs45+RFiYuLr1/kAgR9AYKN6Y0zDEJEcVc0M165FjfRrWuagsMjF5NHJiHs/27bezsiui9l5tD+xHV7nh5kTG6Q/v52cUaXm30b1xpim1qKCfk03S/VKSmD37rfoWnIrSd2K6NPnQU5L/QUxMfWfgK2Jr+bfGGOOBy0q6Ie6WapjmwPcd+prrFv3D9q3H0t6+ku0aze8CXpojDFNq0WVbFa/WUoZ1+vf/OGMW4ivWEy/fr9n9OgvLeAbY1qtFjXS96+gcbm+5Sej/kR6p2V06DCOwYPnkZhoNz0ZY1q3FhX0wRP4T+29gvXrf4pqOf36PUly8q2ItKgvNcYYUydhI6GIJIjIVyKySkTWisj9QdrEi8ibIpIvIstEJM3v2D3e5/NEpGHKZAIkJg6iY8dxjB27mpSUn1rAN8YYr0hG+qXAmap6REQcwBci8rGqLvVrcx1wQFUHiMgU4BHgChEZCkwBhgG9gE9EZJCq1n0LqwgkJqYzYsTfG/ItjDGmWQo7BFaPI96HDu+vwHL4C4FXvD/PB84SEfE+/4aqlqrqViAfOCkqPTfGGFNrEeU9RCRWRFYCu4F/qeqygCbJwLcAqloOHAS6+D/vtcP7nDHGmCYQUdBX1QpVHQWkACeJSGDNY+AOg+D5NhDq+aovFpkuItkikr1nz55IumSMMaYOajXDqapFwKfAuQGHdgC9AUQkDugI7Pd/3isFKAxy3rmqmqmqmd26datNl4wxxtRCJNU73UQkyfuzEzgb2BDQbAFwtffnS4FF6lnJbQEwxVvd0xcYCHwVrc4bY4ypnUiqd3oCr4hILJ4PibdU9UMReQDIVtUFwDzgryKSj2eEPwVAVdeKyFvAOqAcuKWhK3eMMcaE1qKWVjbGmNYq0qWV7a4lY4xpRY67kb6I7AG+qcNLuwJ7o9yd451dc+tg19w61Pea+6hq2EqY4y7o15WIZEfy1aYlsWtuHeyaW4fGumZL7xhjTCtiQd8YY1qRlhT05zZ1B5qAXXPrYNfcOjTKNbeYnL4xxpjwWtJI3xhjTBjNLuiLyLneDVnyRWRmkOMhN3RpriK45p+JyDoR+VpE/i0ifZqin9EU7pr92l0qIioizbrSI5LrFZHLvX/Pa0Xkb43dx2iL4N91qogsFpFc77/t85qin9EkIi+JyG4RWRPiuIjIU94/k69F5MSod0JVm80vIBbYDPQD2gCrgKEBbW4GnvP+PAV4s6n73QjXPAFI9P58U2u4Zm+79sBnwFIgs6n73cB/xwOBXKCT93H3pu53I1zzXOAm789DgW1N3e8oXPdpwInAmhDHzwM+xrNC8SnAsmj3obmN9E8C8lV1i6oeA97As1GLv1AbujRXYa9ZVRerarH34VI8q5k2Z5H8PQM8CPweKGnMzjWASK73BuAZVT0AoKq7G7mP0RbJNSvQwftzR4Ks0NvcqOpneNYnC+VC4C/qsRRIEpGe0exDcwv6kWzKEmpDl+aqthvRXIdnpNCchb1mERkN9FbVDxuzYw0kkr/jQcAgEVkiIktFJHB58+YmkmueBUwVkR3A34HbGqdrTarBN56KZJXN40kkm7JEtHFLMxLx9YjIVCATOL1Be9Twarxm8ex0/zhwTWN1qIFF8ncchyfFcwaeb3Kfi8hw9exx0RxFcs1XAn9W1UdF5Ht4VvIdrqruhu9ek2nw+NXcRvqRbMoSakOX5iqijWhE5GzgV8AkVS1tpL41lHDX3B4YDnwqItvw5D4XNOPJ3Ej/Xb+vqmXq2W86D8+HQHMVyTVfB7wFoKr/BRLwrE/TkkX0/70+mlvQXw4MFJG+ItIGz0TtgoA2oTZ0aa7CXrM31fE8noDf3HO9EOaaVfWgqnZV1TRVTcMzjzFJVZvrmtyR/LvOwjNhj4h0xZPu2dKovYyuSK55O3AWgIgMwRP0W/p+qguAq7xVPKcAB1V1ZzTfoFmld1S1XERuBRbimf1/ST0btYTd0KW5ivCa5wDtgLe9c9bbVXVSk3W6niK85hYjwutdCJwjIuuACmCGqu5rul7XT4TX/HPgBRG5E0+K45pmPoBDRF7Hk6Lr6p2ruA9wAKjqc3jmLs4D8oFi4Nqo96GZ/xkaY4ypheaW3jHGGFMPFvSNMaYVsaBvjDGtiAV9Y4xpRSzoG2NMK2JB3xhjWhEL+sYY04pY0DfGmFbk/wPNvZ2Xu9Nv8QAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 预测\n",
    "xMat = mat(xArr)\n",
    "yMat = mat(yArr)\n",
    "yHat = xMat * ws\n",
    "\n",
    "# 绘图\n",
    "# 数据散点图\n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111)\n",
    "ax.scatter(xMat[:, 1].flatten().A[0], yMat.T[:, 0].flatten().A[0])\n",
    "# 预测回归直线\n",
    "xCopy = xMat.copy()\n",
    "xCopy.sort(0)\n",
    "yHat = xCopy * ws\n",
    "ax.plot(xCopy[:, 1], yHat, color='y')\n",
    "ax.legend((\"prediction\", \"data\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "计算相关性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1.        , 0.13653777],\n",
       "       [0.13653777, 1.        ]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "corrcoef(yHat.T, yMat)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "相关性并不高，线性模型有待改进"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 8.2.局部线性回归（Local Weight Linear Regression）（LWLR）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def lwlr(testPoint,xArr,yArr,k=1.0):\n",
    "    \"\"\"\n",
    "    局部线性回归函数\n",
    "    参数：\n",
    "        testPoint -- 测试点\n",
    "        xArr -- x参数\n",
    "        yArr -- y参数\n",
    "        k -- 核参数\n",
    "    \"\"\"\n",
    "    # 处理数据\n",
    "    xMat = mat(xArr); yMat = mat(yArr).T\n",
    "    # 样本个数\n",
    "    m = shape(xMat)[0]\n",
    "    # 初始化权重\n",
    "    weights = mat(eye((m)))\n",
    "    # 对于每个样本\n",
    "    for j in range(m):\n",
    "        # 求差\n",
    "        diffMat = testPoint - xMat[j,:]\n",
    "        # 高斯核计算权重\n",
    "        weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2))\n",
    "    # 加权的xTx\n",
    "    xTx = xMat.T * (weights * xMat)\n",
    "    # 判断奇异性\n",
    "    if linalg.det(xTx) == 0.0:\n",
    "        print(\"奇异矩阵，求不了逆\")\n",
    "        return\n",
    "    # 公式计算出预测结果\n",
    "    ws = xTx.I * (xMat.T * (weights * yMat))\n",
    "    return testPoint * ws"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def lwlrTest(testArr,xArr,yArr,k=1.0):\n",
    "    \"\"\"\n",
    "    对每个点计算局部权重\n",
    "    参数：\n",
    "        testArr -- 测试矩阵\n",
    "        xArr -- x参数\n",
    "        yArr -- y参数\n",
    "        k -- 核参数\n",
    "    \"\"\"\n",
    "    # 样本点个数\n",
    "    m = shape(testArr)[0]\n",
    "    # 初始化预测结果\n",
    "    yHat = zeros(m)\n",
    "    # 对每个点计算局部权重，得到预测值\n",
    "    for i in range(m):\n",
    "        yHat[i] = lwlr(testArr[i],xArr,yArr,k)\n",
    "    return yHat"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "yHats = []\n",
    "for k in [1.0, 0.01, 0.003]:\n",
    "    yHat = lwlrTest(xArr,xArr,yArr,k)\n",
    "    yHats.append(yHat)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "绘图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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z09l9+7bcXFpyBVXLOKGGww2S662ngteCFE2mTzbAR08+DjZ2cdYsGAJSjWSkShCiFKk5+5gTp/+nlOnvmHDhlA+/7w/J09Kz1kIUZr03B1IdnYse/ZMIC6uH02avCLznwshLkp67g7CaCzgwIFxNG2axwsvfE23bs7SYxdCXJT03B3Er7/Oxd//L37+eTbdurWXHrsQolzSc3cA6enRDB36EgcPjuSuux4mMNDWEQkh7J0kdztnNOZw4sS9NGnizQMPLMDVteYvVBJCOB4py9i59eun0qRJFD/88Bmuro1tHY4QwkFIcrdjycnr6NdvJtu3j+fee2+2dThCCAciZRk7ZTSeITHxXry9O/DEE+/gLD8pIUQlSM/dDmldwO7d/8PD4zQLF36Hs3N9W4ckhHAwktzt0MaNoXTosJLly2eyf39vIiJsHZEQwtFIcrczCQk/YTKF8dtv/+P77yexebN5Wl0hhKgMSe52JD09ir1770ep/kRHf8yMGUqmGBBCXBI5TWcHIiLgvfcOM2HCMFxdfend+yd++cUNkCXshBCXpk723M2LSmM3tex33z3BLbcMISMjl48+Ws2//za1dUhCCAdXJ5N70dJwI0ZcmOArm/St8UciO/sEjz8+FB+fZBYuXMO333aVGrsQosrqZFkmJAT27z/OjTd+yNq1B8nL86RJk3qsX+/F8eO3Exra76IzLhZfELqq64empoaze/edODml0b//r3h79yYjQ2rsQoiqq3PJPSfnJH5+05k/fwFOTgWcOHElSUnZGAwZ9O2bQt++7+DkNJL09NepX79bqdcXT+iVWT+0+B+Fvn1zOHbsdY4dm0FSUmvmzdtAWlp3Zs+WhTeEENZRZ5K70ZjExo3Tufrqj4F8Nm16mM8+e4V69Vry6afmZery89OJi3uP48dnEhnZg8aN78LfPxRPz/bn9lM8oVu6fmhEhLkElJxsokuX74BXyck5xs6d43jppblkZXkB5uQvyV0IYQ21uuZurokXsHHjAlJTr6B37/fYufMupk49wNSpH1OvXkt27z6//qizc31at55Mv35HaNXqRRITl7FlS0f27x9PdvaJC3rfFa1ZWrweHxqqad/+VxYuvIoRI+7n8GE/Pv30d9zdP6d7dy86d4a+faUcI4SwHqW1tskbBwQE6MjIyGrZd1ES9vDYwQ03TKBz580oNYgF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\n",
      "text/plain": [
       "<Figure size 432x720 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 对数据点排序\n",
    "xMat = mat(xArr)\n",
    "srtInd = xMat[:, 1].argsort(0)\n",
    "xSort = xMat[srtInd][:, 0, :]\n",
    "\n",
    "# 绘图\n",
    "fig = plt.figure(num=None, figsize=(6, 10))\n",
    "for i, k in enumerate([1.0, 0.01, 0.003]):\n",
    "    ax = fig.add_subplot(3, 1, i+1)\n",
    "    ax.plot(xSort[:, 1], yHats[i][srtInd], c='y')\n",
    "    ax.scatter(xMat[:, 1].flatten().A[0], mat(yArr).T.flatten().A[0], s=2, c='b')\n",
    "    ax.legend((\"prediction\", \"data\"))\n",
    "    plt.title(f\"k = {k}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 8.3.实例：预测鲍鱼的年龄"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "def rssError(yArr,yHatArr):\n",
    "    \"\"\"\n",
    "    计算回归误差\n",
    "    参数：\n",
    "        yArr -- y数据\n",
    "        yHatArr -- y预测\n",
    "    返回：\n",
    "        L2loss\n",
    "    \"\"\"\n",
    "    return ((yArr-yHatArr)**2).sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 8.3.1.读取数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "abX, abY = loadDataSet(\"abalone.txt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 8.3.2.预测，并计算误差"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "error01 = 56.78420911837208\n",
      "error1 = 429.89056187030394\n",
      "error10 = 549.1181708826065\n"
     ]
    }
   ],
   "source": [
    "# 得到预测值\n",
    "yHat01 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 0.1)\n",
    "yHat1 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 1)\n",
    "yHat10 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 10)\n",
    "\n",
    "# 计算预测误差\n",
    "error01 = rssError(abY[0:99], yHat01.T)\n",
    "error1 = rssError(abY[0:99], yHat1.T)\n",
    "error10 = rssError(abY[0:99], yHat10.T)\n",
    "\n",
    "# 打印结果\n",
    "print(f\"error01 = {error01}\\nerror1 = {error1}\\nerror10 = {error10}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "k = 0.1的结果最好，但是不是一成不变的\n",
    "\n",
    "看看它们在新数据集上的表现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "error01 = 3580.5304330698336\n",
      "error1 = 2568.743170627686\n",
      "error10 = 2648.9694571854866\n"
     ]
    }
   ],
   "source": [
    "# 得到预测值\n",
    "yHat01 = lwlrTest(abX[100:199], abX[100:199], abY[100:199], 0.1)\n",
    "yHat1 = lwlrTest(abX[100:199], abX[100:199], abY[100:199], 1)\n",
    "yHat10 = lwlrTest(abX[100:199], abX[100:199], abY[100:199], 10)\n",
    "\n",
    "# 计算预测误差\n",
    "error01 = rssError(abY[0:99], yHat01.T)\n",
    "error1 = rssError(abY[0:99], yHat1.T)\n",
    "error10 = rssError(abY[0:99], yHat10.T)\n",
    "\n",
    "# 打印结果\n",
    "print(f\"error01 = {error01}\\nerror1 = {error1}\\nerror10 = {error10}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 8.4.岭回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "def ridgeRegres(xMat,yMat,lam=0.2):\n",
    "    \"\"\"\n",
    "    岭回归算法\n",
    "    参数：\n",
    "        xMat -- x数据\n",
    "        yMat -- y数据\n",
    "        lam -- 岭回归参数\n",
    "    返回：\n",
    "        ws -- 预测值\n",
    "    \"\"\"\n",
    "    xTx = xMat.T*xMat\n",
    "    # 加上“岭”\n",
    "    denom = xTx + eye(shape(xMat)[1])*lam\n",
    "    # 判断奇异性，避免lambda为0引发错误\n",
    "    if linalg.det(denom) == 0.0:\n",
    "        print(\"奇异矩阵，没法求逆\")\n",
    "        return\n",
    "    ws = denom.I * (xMat.T*yMat)\n",
    "    return ws"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "def ridgeTest(xArr,yArr):\n",
    "    \"\"\"\n",
    "    岭回归\n",
    "    参数：\n",
    "        xArr -- x数据\n",
    "        yArr -- y数据\n",
    "    返回：\n",
    "        wMat -- 预测\n",
    "    \"\"\"\n",
    "    xMat = mat(xArr); yMat=mat(yArr).T\n",
    "    yMean = mean(yMat,0)\n",
    "    # 去均值化\n",
    "    yMat = yMat - yMean\n",
    "    # 标准化x\n",
    "    xMeans = mean(xMat,0)\n",
    "    xVar = var(xMat,0)\n",
    "    xMat = (xMat - xMeans)/xVar\n",
    "    # 预测点数\n",
    "    numTestPts = 30\n",
    "    # 初始化预测结果矩阵\n",
    "    wMat = zeros((numTestPts,shape(xMat)[1]))\n",
    "    # 逐一预测\n",
    "    for i in range(numTestPts):\n",
    "        # lambda的值指数变化\n",
    "        ws = ridgeRegres(xMat,yMat,exp(i-10))\n",
    "        wMat[i,:]=ws.T\n",
    "    return wMat"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x26c6399eba8>,\n",
       " <matplotlib.lines.Line2D at 0x26c6399e438>,\n",
       " <matplotlib.lines.Line2D at 0x26c6399e7b8>,\n",
       " <matplotlib.lines.Line2D at 0x26c6399e198>,\n",
       " <matplotlib.lines.Line2D at 0x26c6399e048>,\n",
       " <matplotlib.lines.Line2D at 0x26c6399ef60>,\n",
       " <matplotlib.lines.Line2D at 0x26c6399ed68>,\n",
       " <matplotlib.lines.Line2D at 0x26c639b9e10>]"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX8AAAD8CAYAAACfF6SlAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3Xl8XHd97//X55xZNNq30eLd8pLYsR3bUZyQOGQpoUlY0pQQQn+UUkpzaaEtl9vfD/q793eh/NpbbvtruW2h0GyFQFvgFggBEsjmBQhJLMdOYseJLduyLVu2JMvapdnO5/fHjMayLK8aaTQznyecx1nnnO/Jkd/zne985xxRVYwxxhQWJ9sFMMYYM/Ms/I0xpgBZ+BtjTAGy8DfGmAJk4W+MMQXIwt8YYwqQhb8xxhQgC39jjClAFv7GGFOAfNkuwLnU1tbqokWLsl0MY4zJKdu3b+9W1fCFtpu14b9o0SJaWlqyXQxjjMkpInLoYrazZh9jjClAFv7GGFOALPyNMaYAWfgbY0wBsvA3xpgCZOFvjDEFyMLfGGMK0Kzt53+5YpEEr/zsorq5Ti+Z5l3KmQeQSY6XXCbpF4/fRlIzIoI4qXlJzQuIkxqnlruu4LgOjivJwZecPnO5g8/v4C9yCYZ8uH4nfRxjzOySd+EfjyZoeaotu4WwxyID4DiCP+QSKPIlh5BLIDQ27aO8pojK+mIq64qpCIdw/fZB1JiZknfhHyoL8Imv3pbtYkwr1QnvLjrJpOq46dMrFD09ral9pcZj8+qdudzzFPWURFzxEoqX8NLjRGJsmeLFPeIxj9honMhInOhoglhqHB2NEx2NM9wXpff4MJHhOKNDsXS5RaCspij5RpB6Q6isD1FZV0xpdRGOY58gjMmkvAv/QnBWU4pMNjn7wzIyEqevc5jeE6mhc4TeE8N07O8gFkmktwuV+bni+kZW3thIVUNJFktsTP6w8DdZEwz5qFtYTt3C8jOWqyrD/VH6Ooc5dXyYw7t7eO25I+x85jANTRWs3NjIkvV1BIrsz9eYyyVnNSHMEs3NzWo3djNjhvujvPliB3t+2UHviWH8QZdlzXWsuHEO9YvL7YtlY1JEZLuqNl9wOwt/k0tUleP7+3jjhQ5aW04Qj3pUzylhxQ2NXHF9A6HSQLaLaExWWfibvBcdibOv5QR7XujgxMF+HJ/w9g8s56qb5ma7aMZkzcWGvzWampwVCPm46qa5XHXTXE4eHeSF77ey+V/fIjqSYN07F2S7eMbMatax2uSFmrml3PUHa1h6TR0vfL+Vl544cHaXWGNMmtX8Td5wfQ63/95V+IMuLU+2ERtNcOP7l9qXwcZMYso1fxGZLyKbRGSPiOwWkT+ZZBsRkX8QkVYReU1E1k/1uMZMxnGEWz90JWtuncerzx9h87fexPPsE4AxE2Wi5h8H/ouqviIiZcB2EXlGVd8Yt82dwLLUcB3w1dTYmIwTR9h43zICIR8tT7YRjSR4x++uxHWtldOYMVMOf1XtADpS0wMisgeYC4wP/7uBxzTZCPuiiFSKSGPqtcZknIhw3Xub8AddfvWD/cQjCX79gVX4/G62i2bMrJDRqpCILALWAS9NWDUXODJuvj21zJhptf7XF3LzB5fTtuskP/7ya0RH49kukjGzQsbCX0RKge8Bn1LV/omrJ3nJWQ2xIvKAiLSISEtXV1emimYK3Kqb5/GOj6zk2L5envj7nWfcUM6YQpWR8BcRP8ng/1dV/f4km7QD88fNzwOOTdxIVR9U1WZVbQ6Hw5komjEAXHFdA3f8/iq6Dg/w+Jd2MNwfzXaRjMmqTPT2EeARYI+q/t05NnsC+HCq18/1QJ+195uZ1rQuzLv+cA19J4b58ZdfRa0XkClgmaj53wj8NnCbiOxMDXeJyMdF5OOpbZ4EDgCtwEPAH2bguMZcsgVX1XDLh66k6/AAra90Zrs4xmRNJnr7/IIL3Dw+1cvnE1M9ljGZsOzaerY/1ca2n7SxZH2dPSjGFCTr+GwKjuMI1757Mac6hti/3Wr/pjBZ+JuCtHR9HdVzStj2k4P2C2BTkCz8TUESR7j2XYs5dXyY1pYT2S6OMTPOwt8UrCXrwtTMLWHbT9rwEl62i2PMjLLwNwVrrPbfe2KYfdus9m8Ki4W/KWhNa8PUzCu12r8pOBb+pqCJI2x492L6ukbY+7LV/k3hsPA3BW/x1bXUzi9l25NW+zeFw8LfFDyRZO2/v2uEt146nu3iGDMjLPyNARatqSW8oIyWJ9tIWO3fFAALf2MYV/vvHuWtX1nt3+Q/C39jUhaurqFuYar2H7fav8lvFv7GpIgIG97TxEDPKG/+yu44bvKbhb8x4yy4qpr6xeW0PGW1f5PfLPyNGWes7X+wJ8KeF6z2b/KXhb8xE8xfWU1DUznbn2ojEbPav8lPFv7GTJCs/TcxeCrCG78861HTxuQFC39jJjFvRRWNSyvY/lQb8Vgi28UxJuMs/I2ZhEjyaV9DfVH2bbOnfZn8Y+FvzDnMu6KKsuoi9u+w8Df5x8LfmHMQEZrWhznyRg+RkXi2i2NMRln4G3MeS9bV4SWUtte6s10UYzIqI+EvIo+KSKeI7DrH+ltEpE9EdqaG/56J4xoz3RoWl1NSEeDAjq5sF8WYjMpUzf/rwB0X2Obnqro2NXwhQ8c1ZlqJIzStDXN490liEev1Y/JHRsJfVbcCPZnYlzGzzZL1dcRjHod2ncx2UYzJmJls83+biLwqIk+JyFUzeFxjpqRxWSWhMr/1+jF5ZabC/xVgoapeDfwj8PhkG4nIAyLSIiItXV3WxmpmB8cRFl8d5tDrJ+0HXyZvzEj4q2q/qg6mpp8E/CJSO8l2D6pqs6o2h8PhmSiaMRdlybowsUiCI29Y66bJDzMS/iLSICKSmt6QOq41oJqcMfeKKoLFPvZbrx+TJ3yZ2ImI/DtwC1ArIu3A5wA/gKp+DbgX+AMRiQMjwP2qqpk4tjEzwfU5LF5Ty4FXu0nEPVyf/UTG5LaMhL+qfvAC678MfDkTxzImW5rW1/Hmi8dpf+sUC6+qyXZxjJkSq74Yc5Hmr6jCH3Q58Ir1+jG5z8LfmIvk87ssWl3DgVe78RL2kBeT2yz8jbkETevqGB2Mcay1L9tFMWZKLPyNuQQLV9Xg8zvst6Yfk+Ms/I25BP6gy4JVNRzY2YV61mHN5C4Lf2Mu0ZJ1YYb7ohw/YE0/JndZ+BtziRatrsXxif3gy+Q0C39jLlEg5GPBimr27+jEfqtocpWFvzGXoWldHYM9EToPDWS7KMZcFgt/Yy7D4qtrcRzhgN3m2eQoC39jLkNRiZ+5V1Sy/5Uua/oxOcnC35jL1LSujr6uEU4eHcp2UYy5ZBb+xlymprVhRLAffJmcZOFvzGUqLg/QuLTSunyanGThb8wULFkf5lTHEKeOW9OPyS0W/sZMQdPaOgD2v2K1f5NbLPyNmYLSqiD1i8vZb10+TY6x8Ddmipasr6P7yCB9XSPZLooxF83C35gpWrIuDGC1f5NTLPyNmaLy2hDhBWUcsF4/JodY+BuTAU3rwpw42M/gqdFsF8WYi2Lhb0wGnG76sdq/yQ0ZCX8ReVREOkVk1znWi4j8g4i0ishrIrI+E8c1ZraoaiihqrHEmn5MzshUzf/rwB3nWX8nsCw1PAB8NUPHNWbWWLIuTEdrL8P90WwXxZgLykj4q+pWoOc8m9wNPKZJLwKVItKYiWMbM1ssWR9GFQ6+arV/M/vNVJv/XODIuPn21LIziMgDItIiIi1dXfYPyOSWmrmllIdD1u5vcsJMhb9Msuysm6Cr6oOq2qyqzeFweAaKZUzmiAhL1oU5+uYpRodi2S6OMec1U+HfDswfNz8PODZDxzZmxjStC+N5Stvr3dkuijHnNVPh/wTw4VSvn+uBPlXtmKFjGzNj6heWU1oVtBu9mVnPl4mdiMi/A7cAtSLSDnwO8AOo6teAJ4G7gFZgGPjdTBzXmNlGHKFpbZjdPz9GdDROoCgj/8SMybiM/GWq6gcvsF6BT2TiWMbMdkvWh3ltUzuHdp1kWXN9totjzKTsF77GZFjDkkpCZX77wZeZ1Sz8jckwxxEWrw3Ttusk8Wgi28UxZlIW/sZMgyXrwsQjCQ6/cb7fPhqTPRb+xkyDuVdUESz2cWCnNf2Y2cnC35hp4LoOi9bU0vZaN4m4l+3iGHMWC39jpsmSdWEiw3GOvnUq20Ux5iwW/sZMk/krq/EHXfZb04+ZhSz8jZkmPr/LwtU1HNzZheeddSsrY7LKwt+YadS0NszIQIyO1t5sF8WYM1j4GzONFq6qwfU7dptnM+tY+BszjQJFPhasrObAji7Umn7MLGLhb8w0W7IuzFBvhBOH+rNdFGPSLPyNmWYLV9fiOMIBu82zmUUs/I2ZZkUlfuZdWcX+HZ0kb3BrTPZZ+BszA5rWhenvHuXk0cFsF8UYwMLfmBmx+OowItgTvsysYeFvzAwoLg/QuLTSunyaWcPC35gZsmR9mFMdQ5w6PpTtohhj4W/MTGlaWwdgtX8zK1j4GzNDSquC1C8ut8c7mlnBwt+YGdS0LkzX4QH6u0eyXRRT4DIS/iJyh4i8JSKtIvLZSdZ/RES6RGRnavhYJo5rTK5Zur4OBHZtPZrtopgCN+XwFxEX+ApwJ7AS+KCIrJxk0++o6trU8PBUj2tMLiqvDbGsuZ7XN7czMhDNdnFMActEzX8D0KqqB1Q1CnwbuDsD+zUmL137rkUkYh47njmc7aKYApaJ8J8LHBk3355aNtH7ROQ1EfkPEZmfgeMak5OqGkpYdm2y9j/cb7V/kx2ZCH+ZZNnEG5j8CFikqmuAZ4FvTLojkQdEpEVEWrq6rEeEyV/NdyVr/zut9m+yJBPh3w6Mr8nPA46N30BVT6pqJDX7EHDNZDtS1QdVtVlVm8PhcAaKZszslK79b7Hav8mOTIT/NmCZiCwWkQBwP/DE+A1EpHHc7HuBPRk4rjE5baz2b23/JhumHP6qGgc+CfyMZKh/V1V3i8gXROS9qc3+WER2i8irwB8DH5nqcY3JdVUNJSzbUM8ua/s3WSCz9f7izc3N2tLSku1iGDOtek8M82+ff5Gr37GAG9+3NNvFMXlARLaravOFtrNf+BqTRZX1xSzf0GC1fzPjLPyNybLmuxaRiHvsePpQtotiCoiFvzFZlq79bzlqtX8zY3zZLoAxJln73/vycbY91cryt1fR09NDT08P0WiUYDBIUVERwWBw0ulAIIDjWD3OXBoLf2Nm2PDwMCdPnuTUqVPpkO/p6eFUYxeb9kTYNK4jtIhc1EPfi4qKmD9/PkuXLmXp0qXU1NRM4xmYfGDhb8w0SyQStLe309rayr59+zh+/PgZ68vLy6muruaKK67g4MsDNK2cxw13raS6uppAIEAsFmN0dJRIJEIkEpl0enBwkIMHD7Jv3z4AqqqqWLZsGUuXLmXRokUEAoFsnLqZxSz8jZkGAwMD6bA/cOAAo6OjiAjz58/ntttuo76+nurqaiorK/H7/enXPTvyBvu3d1J+bzXBYBCAQCBw0eHd09OTPu4rr7zCyy+/jOu6LFy4kKVLl7Js2TJqa2sRmeyuLKaQWD9/YzJgrHa/b98+Wltb07X70tLSdA28qamJUCh03v30dg7zb59/iTW3zWPjvcumVKZYLMbhw4fTbwbd3d0AhMNhNm7cyKpVq3Bdd0rHMLPPxfbzt/A35jINDw/T2trK3r17aW1tPaN2Pxb4DQ0Nl1zLfu7rb9C6vZMP/cXbKKkIZqy8vb297Nu3j23bttHZ2UlVVRU33XQTa9asweezRoB8YeFvTIapKt3d3ezdu5e9e/dy+PBhVJXi4mKWL1/OsmXLLqp2fyHp2v+t89j4/qnV/ifjeR5vvfUWW7dupaOjg4qKCjZu3MjatWvPaIIyucnC35gMiMfjHDp0KB34p06dAqC+vp7ly5ezfPly5s6dm/Guls994w32tXTy2xmu/Y+nqrS2trJlyxba29spKyvjhhtu4JprrrEviHOYhb8xlyiRSNDV1UVHR0d6OH78OLFYDNd1aWpqSgd+RUXFtJZlrPa/6u1zefv9y6f1WKrKwYMH2bp1K21tbRQXF3PDDTdw7bXXpr90NrnjYsPfGvpMQYrFYnR2dp4R9CdOnCCRSADg9/tpaGhg3bp1LFmyhMWLF89obbiyrpiVG+fw+uZ2ikr9XPuuRdPWQ0dEaGpqoqmpiUOHDrF161aeffZZfvnLX/K2t72N6667zt4E8pDV/E1eicViDA4OpoehoaEz5seGvr6+9I+nioqKaGxspLGxkYaGBhobG6mpqcn6r2YTCY/N33yTN188zqqb53LTB5bjODPTRfPo0aNs2bKFvXv3EgqFuOGGG9iwYYO9CeSAgm32icfj7N+/fxpKlH8u9tpP3G78/GTrxpZdaFpV8TzvnMPY+ng8TjweJxaLnXOIx+NEo1Gi0cnvjVNcXExpaWl6qKioSAd+ZWXlrO33rqr86gf72fH0YZasD3P7716F65+5N6WjR4+yefNm9u3bl24O2rBhg30nMIsVbPgPDQ3xN3/zN9NQIjPTHMdJD4FAAL/fj8/nw+/3n3MoKSmhpKTkjKAvKSnJ+f7sO545zAvfa2XuFVXc9fHVBEIz22Lb3t7Opk2b2L9/P8XFxWzcuJHm5mZ7E5iFCjb8R2OjvLz35WkoUe6Yci12kpfL2EI5/7L08SW1fvw4Va6x+9WIIziOg4ggjiCSmk9Nj1HO/huddNnETyHoWcvHL5s4rejp5Up62cTtx+9z7DVjHEmejyMODuOmxUmvd8Qh4AYIOkGCviBFbhEBN0CRr4iAEzjn9XvrxQ6ef+xNauaV8u5PXk1x+cwH75EjR9i0aRMHDhygpKQk/SZgXURnj4IN/57RHm7+zs3TUCJjZkbQDSbfDNwiiv3FVAYr00N15wKCzzfhligLPiiEGyqoClZRWVRJdVF1+k1muh06dIjNmzdz8OBBSktLuf7661m1ahWVlZUzcnxzbgUb/tFElBc7XpyGEplskkk+jkxWQx7bbuKnkvGvT38CGfvf+HmRM8aTbT+2bPwxBEl/YvDUwyP1nYV6eOqhaHqc8BJEE1EiXoRIPEIkMcmQWj4UG6I30ktfpI9TkVP0RfooP1XPnXseIOHEeXLF1zhZcgwAn+OjvriexpJGGksaaShpoKGkIT3fWNpIib9kKpfhLG1tbWzevJm2tjYA5s2bx1VXXcXKlSunvTusmVzBhr8x+W40PsrhQyfY+mAbsdEEDe+LMVrXw4mhE3QMdXB86DgdQx10DneS0MQZry0LlNFY0sic0jnMK53HnNI5Z0yXBcouq0w9PT3s3r2b3bt3p+9rtGDBgvQbQVnZ5e3XXDoLf2Py3EDPKD/6h530d4/yzt+7iqZ14TPWx7043SPd6TeDjqEOjg0e4/jQcY4OHuXo4FFG4iNnvKYsUHbGm0JDcQP1JfXUF9fTUNJAbagWn3P+L5u7u7vTbwSdnZ0ALFy4kFWrVrFixQpKS0sz+x/CnMHC35gCMDoY48dfeZXOtn7mrahm0eoaFq2upbz2wvcXUlV6I70cGzzG0cGj6fHY9LGhY2e9OTjiUFtUm35DqC+pp6G4gdriWqqLqqkpqqG6qJrKokr8jp/Ozs70G8HYXUWrq6upq6ujrq6O+vp66urqqK6uzvkeWbPFjIa/iNwB/D3gAg+r6hcnrA8CjwHXACeBD6hq2/n2ebnh3zcS4+Pf3H7JrzMzb8qdks7TK2niuvHfD0h6GTiSfEVytZDqqJQaJ+cdR3BEcFPbJ+fBTS13RNLTfp/gdxx8ruB3Hfyu4HMc/D4HvyP4UstCfpfigI9QwKU4NSSnfYT8Lu4l/JgrFknQ8mQbB3Z20XtiGIDqOSUsWlPL4jW11C0qv6wfh6kqfaO9nOhtp6vvGF39HZzsP05PfyenBjvpHeiib7CbRGQUX4Lk4JGeLpMQ5U4x5RKiREL4nXJGpZJRp4hhCTCMm75QDkolUINQDVR7SoUIxT5f8jGVgQDi9yeHidMBP05JCW55OU5pKW55OW5ZGVJcPGt/vzGdZuz2DiLiAl8BbgfagW0i8oSqvjFus98DTqnqUhG5H/ifwAemeuzJaCTC6td/Ph27Nhk0WVfNDOz0jH3rhOXjJ0WTW2mqS2f6tTrxtYqniurY9Oll8XHTCqiX/FFawjvd/TP9RoMi4wokqTKcXqepbZNjn0DAFYp8QrHPIeRzCPmEkE8och1CLgR9Qsh1CLhQ4whzHCVSE6RjtIrjnTXs+OkAr/z0EAEi1Mtx6r12woljuPFRNBZLDtHo6emJQzQK8TgANanh0gylhjMlBDwH4q5LX3kZfZWV9FdUMFBeweHyCvaFimHszSoRxxmMEBwdpSgSoWh0lODYeDSSnI6M4ovF8cdi+OJxfPHktCOCO/amUFaGW1aGU16GW1GBW16RHFeU41ZU4Iwtq6xIby95/lzkTPxSZAPQqqoHAETk28DdwPjwvxv4fGr6P4Avi4joNLQ5lXpR7nnm0Uzv1phZwUNQETwET5LTMXGIIiTEIeE4+ByXua5LfaCEgcor6K9YzrHSJRxxFyJunBKvG18ggs8fwV8cwa8R/Izg1xECOkxABwnoIP5EP0IMcYDUkPxNxth8alpOzyPJT0vqJMekyiiOD5EylHI8pwiVIEqAEgkSIkCDBIEAQoB4zGUIjxHxiBAnInEiRXGioQTDxOmVGBHieHL++BAFnzq4KvjGBk9wEuCejOF2deN4XTiquJ7iJDwcTY09D0m+pad6c6XGounzFscB10lNC+K6qf8WDuI66fWO44Dr4rgOOA7qpD5Vpr47EdeB1CfH5H9Dh1BFOTfc9/5p+zuCzIT/XODIuPl24LpzbaOqcRHpI1mR6M7A8c/gVlSw5NlnM71bkyMu6VP+pO1GF1gmp+vyp5eNXy2ntznXePx24wdOB+b4QZxkaJCIINEhEpFBhgZOMdjfy/BgH6OD/USG+5ChHnzDPcjoKfyRXoKxXhbFt1Ca+BGl3jAnY0s5GLmWU/H5xDREVEMMepVENURUS1Auv6ZbpBBSISQQktPjYgeKHKFoYrOTnh6rKjH1iGucuBcjplGKvFESXhTFB6kusuCNe5lHHI+oeEQdj4SjyU8UAgkHEpKcT4gSFyUhXnLsJscRFE+UBB4JUTw84ggqkGy9nsr3D15yUCB+eXuoOhTihvumUISLkInwn+yf28S35IvZBhF5AHgAkt3ELqswsUECWz51Wa81M20aGv2ZGLRnB++Zr5dLHDNhGWeu01RtUUmNz0i5ZN//aBGJqIvGXLyYixf34cV8aNyPFw/gJQJ4iSCeVwSeIDqK6AhCBCGKSBSIUkyUEiKIxBAiODKI4wzjBAWn2IdTXodTthAproTiauqDVZT5yhl2Kxj1VzDsq2TIKWfYLWM4LoyOxhkdjhMZiTE6Eic2mkAV3IRSHPMIxTxCUY/iWGqIJodQ7Oy3jZgDI0GXkYBDb9Bh2OcxMtzJUP9hIiMniQ33EBvqJhYfJqGx0y/0BXBKqnBKKnFKyxBfAFw/4voRnx9xA+BLzY8tc3zgnA5rRVIV9vHXXPAp+FSTHwm8sXY+LzmtiniKxOOIF0MSMVAP8RKgcdTzUPWQ1Bj1Upc0+QlB1Us266XGSqpZb9zlH9cumf7LVFKfKias9vm8s/9eMywT4d8OzB83Pw84do5t2kXEB1QAPRN3pKoPAg9C8gvfyyqNejDUdVkvNTNoyi1+k7xe9cx1kzb6nxnGlzRO7+pc6zT9ppDQUuKJeuKJhuQ4Xkc8UUc8Xody7tsyiBPBcaM4bhQJxBAXVCvx1I+qLzl4Dppw0GTV9uydRID+cfsMusk3g2I/TsiHz+9QqlDiKWGNgteNepqssKompxU07uENRPGGJ1RfHcGtCODWhfBVFuFWBtODryI5lqDLyfbDHNzRwtEd2zj21h68RIJAqJjqOXOpnd9AWe1qysN1lNWGKa+to7w2TFFpWUF+SZsNmQj/bcAyEVkMHAXuB35rwjZPAL8D/Aq4F3h+Otr7AQhVwQObp2XXxoynCY/4yVHincPEuoaJd40Q704OZwSmI/iqi/DVhgjWhvDVFuGUBHBCLk6RDyeUHCToQ9xLCz5VhbiisQTeSDw5DMfxhmNnTg+PrYvhDcWSbctj7fJjbfU+wHGSPYNS7c/u4opkqFcGcatSQV8WQCbpPRSLjHJk9+sc+PE2Du5sob8r2cc/vGARze/5TRava2bOsitxrEvnrDDl8E+14X8S+BnJhrJHVXW3iHwBaFHVJ4BHgG+KSCvJGv/9Uz2uMTPFiySIdw0T6xpJBn3nMPHOYeInR083HwBueQBfOERodS2+2mJ84RC+2hC+qmDyS71pICLgF8Tv4BTP/M3VVJW9L/6C3Zuf5cju14nHoviCQRauXst1v3Efi9c1U1ZTO+PlMhdmP/IyBc2LJEj0R0j0R5NDXwSvP3p6WV+ERN+4ZwQ44KsJ4QsX468rxlcXwh9Ojp1gYT0Y79jeN9n82EN07HuLivoGlqzfwOJ1zcxbuRqf3eUza+wxjibn6NgXZKc74CeXeYomxsYeJMbNx71kG3UiuU4jHl40gUbiyelIHI0k8CIJNJpIT3vDMRJ9UTSSOKscEnRxywO4FUGCSyrx1YaSQR8O4asJIb787v99If1dnWz9t6/z1gtbKams4tc//iesvPk2HMeac3JJ3oV/YijGiS8V8C98L+mD3EVufJ7NzvrgmP5C9PzLdPyy8aGfaQIScJNfegZT44CLP1xM0dIqnPJAMujLg8kvMcsDBVeDv1jRkWFeevx/s/0njyMI17/vfq597/sIFF34VhJm9sm7v3LxCaGrLv23iHllOnpLnGeXk/bOOKOX3Zm3Vx7rHnm6TzvpeyqklzkT5l1J/nDGTX1R6Z5ehpt6GIwr44LehwRdxO9M+uWkuXiel2DXpmf45Xe+xXBfLytuupWN93+Y8trwhV9sZq28C38n6KPqnmXZLoYxeeHQazvZ/M2H6T7cxpwrVvIb/9f/Q+PSK7JdLJMBeRf+xpipG+o9xdMP/iMHtr9Mebied3/qsyy//kZbC08hAAANR0lEQVTrg59HLPyNMWfoaH2LJ/72fzA6OMhNv/UR1t/5Xnz2oPa8Y+FvjEnbtekZnn3knyiprOaD/+/fULeoKdtFMtPEwt8YQyIeZ/NjD7PzZz9mwaqrefenPkOorDzbxTLTyMLfmAI33NfLj770Rdr37OKad9/D23/rI3YLhgJg4W9MATu+fx8//Nu/ZHRggLv+6E9ZsfGWbBfJzBALf2MK1O4tz/HMQ1+mpLKK+7/w19QvXpLtIpkZZOFvTIFJxONs+dYj7HjqR8y/ag3v/tRnKC6vyHaxzAyz8DemgAz39/GjL/0V7W/sYv1dd3Pzhz5q7fsFysLfmAJxvHUvT/zdXzHS38edn/g0K99+W7aLZLLIwt+YAvD680/z3CP/RElVdbJ9v2lptotksszC35g8Fo/F2PQv/8xrz/2UBavX8q4//j+tfd8AFv7G5K2Bk9088Xf/g+Ote9lw973ceP9v2z33TZqFvzF56Mgbr/Pj//U/iUUivOfTf8by627MdpHMLGPhb0weUVVeefKHbPnWo1Q2zOG+//5X1Mybn+1imVnIwt+YPBEbHeXpB/+RN3+5haXXXs8df/hpgsXF2S6WmaUs/I3JA73HO/jh3/4l3UcOsfH+D7Ph7nsRp7CfNWzOz8LfmBymquza9AxbvvkIIsL7Pvt5Fq29JtvFMjlgSuEvItXAd4BFQBtwn6qemmS7BPB6avawqr53Ksc1xsDJo0d49qGv0L5nF3OvXMmdn/g0FXUN2S6WyRFTrfl/FnhOVb8oIp9NzX9mku1GVHXtFI9ljCHZd//lx7/Ly4//b3zBILc/8EesvvV2a+Yxl2Sq4X83cEtq+hvAZiYPf2NMBhx543WeeegrnDrWzpU33swtH/4YJZVV2S6WyUFTDf96Ve0AUNUOEak7x3ZFItICxIEvqurjk20kIg8ADwAsWLBgikUzJn+MDPSz5VuPsnvzs1TU1fObf/bnLLa2fTMFFwx/EXkWmKwh8b9ewnEWqOoxEWkCnheR11V1/8SNVPVB4EGA5uZmvYT9G5OXVJU9v9jM5sceZnRwgGvvvpe3ve9+/MGibBfN5LgLhr+qvuNc60TkhIg0pmr9jUDnOfZxLDU+ICKbgXXAWeFvjDmt93gHzz7yTxx6bQeNS6/g9v/2F4QXLs52sUyemGqzzxPA7wBfTI1/OHEDEakChlU1IiK1wI3AX0/xuMbkrVhklJd/+B9se+J7uD4/v/bRP2DN7XfYfXlMRk01/L8IfFdEfg84DLwfQESagY+r6seAFcA/i4gHOCTb/N+Y4nGNyTuqSmvLi2z+xkP0d3Vy5Y03c/OHPkppdU22i2by0JTCX1VPAr82yfIW4GOp6ReA1VM5jjH57lTHUZ7/+oO07dxO7fyF3Pe5v2L+SvtnY6aP/cLXmCyKjY7y0uPfpeVH38f1B7jlw7/P2l9/F67P/mma6WV/YcZkgarS+vKv2PTYQwx0d7Hyplt5+4c+an32zYyx8DdmhvUcO8rz//I1Dr22g/CCRdz153/KvCuvynaxTIGx8DdmhnhegpYf/YAXvvstXH+AWz/yn1j7zrtwXOvFY2aehb8xM+DU8WP89Ctf4tjePSy77gZ+7aN/YE08Jqss/I2ZRqrKq888xZZvPYLr83HXH/0pV954MyKS7aKZAmfhb8w0GTjZzc++9vccem0Hi65ezzs//seUVddmu1jGABb+xmScqvLmLzbz3L98jUQ8zjs+9oesecedVts3s4qFvzEZNNzfx7MPf4V9L73AnOUruOMT/5mqhjnZLpYxZ7HwNyZD9m9/iaf/+R+JDA1y0299hOb33GP34zGzloW/MVM03N/H1m89yu4tzxFeuJh7/9tfEF6wKNvFMua8LPyNuUyqyhtbn2fzNx8hOjzEdfd8gLfdez+uz5/tohlzQRb+xlyGUx1Hefbhf+LwrleZs3wFt//+J6i12r7JIRb+xlyCRDzGtie+z4vf/zY+fyDZk+fX7rCHp5ucY+FvzEU6+uYbPPPQlznZfpjl12/k1o88QGlVdbaLZcxlsfA35gJGhwb5+b9+ndee+ylltWHu+cznaFp/bbaLZcyUWPgbcw6el2Dvr37B5sceZrivj2ve9RvccN//QaAolO2iGTNlFv7GTDDQ082uTc/w+vNPM9DdRX3TUu75zOeob1qa7aIZkzEW/sYAXiLBwZ0tvPbsTzm4YzuqHgtWr+XmD32UZRtusNsum7xj4W8KWn9XJ69veppdzz/N4Kkeiisqufbu97H61ndS2dCY7eIZM20s/E3BicdiHHxlG689/zPaXn0FgMVXr+e2j36cpvUb7Pm5piBM6a9cRN4PfB5YAWxQ1ZZzbHcH8PeACzysql+cynGNuVgjgwN0tR2k69ABOtsO0NV2gJNHj+AlEpRW13D9b97P6ltvpzxcl+2iGjOjplrF2QX8JvDP59pARFzgK8DtQDuwTUSeUNU3pnhsY4DkbRZioyMM9fXSfeQQXW0H6Gw7SGfbfga6u9LblVRVU7dwMU3XbGDOFStYtGa9teWbgjWl8FfVPcCF7lO+AWhV1QOpbb8N3A1Y+Bco9Tw8z8OLx4nHosRjURKxOIlYlHgsRiIWJRGLpaZjREdHGOnvZ3Swn5GBfkb6+xkZHEhOD/QzOtBPIh5P71/EoWrOXOZesZLwOxdTt6iJ8MLF9thEY8aZicbNucCRcfPtwHXTdbCRwQG+87nPTNfuL4qqZvPgZy+64LY6btG4rXVspKCa2lyT2+jp5agmN9XkOs/zIBXwmho8z0M1OX25RByKSksJlZUTKi+noq6BhiXLCZWXEyotI1ReQc28+dTOX4g/WHTZxzGmEFww/EXkWaBhklX/VVV/eBHHmOxjwaR5JCIPAA8ALFiw4CJ2fTbHcaiZO/+yXptR2Xxq0yTHPmdpUtue69NberlIch8iqWWS/H9qOjlKrhPHxXGc1LSDOE5yfmyQ5Lzr9+P6/fj8gfR0et7nxxfw4/r8+ItChMrLKSousXvoGJMhFwx/VX3HFI/RDoxP43nAsXMc60HgQYDm5ubLqj4Hi0t4z6f/7HJeaowxBWMmqlHbgGUislhEAsD9wBMzcFxjjDHnMKXwF5F7RKQdeBvwExH5WWr5HBF5EkBV48AngZ8Be4DvquruqRXbGGPMVEy1t88PgB9MsvwYcNe4+SeBJ6dyLGOMMZlj354ZY0wBsvA3xpgCZOFvjDEFyMLfGGMKkIW/McYUIMnqrQjOQ0S6gENT2EUt0J2h4swG+XY+kH/nlG/nA/l3Tvl2PnD2OS1U1fCFXjRrw3+qRKRFVZuzXY5Mybfzgfw7p3w7H8i/c8q384HLPydr9jHGmAJk4W+MMQUon8P/wWwXIMPy7Xwg/84p384H8u+c8u184DLPKW/b/I0xxpxbPtf8jTHGnEPehb+I3CEib4lIq4h8NtvlyQQRaROR10Vkp4i0ZLs8l0pEHhWRThHZNW5ZtYg8IyL7UuOcesbiOc7p8yJyNHWddorIXefbx2wiIvNFZJOI7BGR3SLyJ6nlOXmdznM+uXyNikTkZRF5NXVOf55avlhEXkpdo++kbp1/4f3lU7NP6mHxexn3sHjgg7n+sHgRaQOaVTUn+yeLyNuBQeAxVV2VWvbXQI+qfjH1Jl2lqtl9/uYlOMc5fR4YVNX/L5tluxwi0gg0quorIlIGbAd+A/gIOXidznM+95G710iAElUdFBE/8AvgT4BPA99X1W+LyNeAV1X1qxfaX77V/NMPi1fVKDD2sHiTRaq6FeiZsPhu4Bup6W+Q/IeZM85xTjlLVTtU9ZXU9ADJZ2/MJUev03nOJ2dp0mBq1p8aFLgN+I/U8ou+RvkW/pM9LD6nL3iKAk+LyPbUc47zQb2qdkDyHypQl+XyZMonReS1VLNQTjSRTCQii4B1wEvkwXWacD6Qw9dIRFwR2Ql0As8A+4He1EOz4BIyL9/C/6IfFp9jblTV9cCdwCdSTQ5m9vkqsARYC3QAf5vd4lw6ESkFvgd8SlX7s12eqZrkfHL6GqlqQlXXknwW+gZgxWSbXcy+8i38L/ph8bkk9WQ0VLWT5JPTNmS3RBlxItUuO9Y+25nl8kyZqp5I/eP0gIfIseuUakf+HvCvqvr91OKcvU6TnU+uX6MxqtoLbAauBypFZOypjBedefkW/nn3sHgRKUl9YYWIlADvBHad/1U54Qngd1LTvwP8MItlyYixkEy5hxy6TqkvEx8B9qjq341blZPX6Vznk+PXKCwilanpEPAOkt9lbALuTW120dcor3r7AKS6bv0vwAUeVdW/zHKRpkREmjj9nGQf8G+5dk4i8u/ALSTvPngC+BzwOPBdYAFwGHi/qubMF6jnOKdbSDYnKNAG/Kex9vLZTkQ2Aj8HXge81OL/m2Q7ec5dp/OczwfJ3Wu0huQXui7Jivt3VfULqYz4NlAN7AA+pKqRC+4v38LfGGPMheVbs48xxpiLYOFvjDEFyMLfGGMKkIW/McYUIAt/Y4wpQBb+xhhTgCz8jTGmAFn4G2NMAfr/AfEvICh2KzpGAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 得到30个点的预测结果\n",
    "ridgeweights = ridgeTest(abX,abY)\n",
    "\n",
    "# 绘图\n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111)\n",
    "ax.plot(ridgeweights)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 8.5.前向逐步回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "def regularize(xMat):\n",
    "    \"\"\"\n",
    "    按行标准化\n",
    "    参数：\n",
    "        xMat -- x数据矩阵\n",
    "    返回：\n",
    "        inMat -- 标准化结果\n",
    "    \"\"\"\n",
    "    inMat = xMat.copy()\n",
    "    inMeans = mean(inMat,0)\n",
    "    inVar = var(inMat,0)\n",
    "    inMat = (inMat - inMeans)/inVar\n",
    "    return inMat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "def stageWise(xArr,yArr,eps=0.01,numIt=100):\n",
    "    \"\"\"\n",
    "    逐步前向回归\n",
    "    参数：\n",
    "        xArr -- x数据\n",
    "        yArr -- y数据\n",
    "        eps -- 每次迭代需要调整的步长\n",
    "        numIt -- 迭代次数\n",
    "    返回：\n",
    "        returnMat -- 返回矩阵\n",
    "    \"\"\"\n",
    "    xMat = mat(xArr); yMat=mat(yArr).T\n",
    "    # 去均值\n",
    "    yMean = mean(yMat,0)\n",
    "    yMat = yMat - yMean\n",
    "    # 正则化\n",
    "    xMat = regularize(xMat)\n",
    "    # x矩阵的维度\n",
    "    m,n=shape(xMat)\n",
    "    # 初始化返回矩阵\n",
    "    returnMat = zeros((numIt,n))\n",
    "    ws = zeros((n,1)); wsTest = ws.copy(); wsMax = ws.copy()\n",
    "    for i in range(numIt):\n",
    "        #print(ws.T)\n",
    "        lowestError = inf; \n",
    "        for j in range(n):\n",
    "            for sign in [-1,1]:\n",
    "                # 调整步长\n",
    "                wsTest = ws.copy()\n",
    "                wsTest[j] += eps*sign\n",
    "                yTest = xMat*wsTest\n",
    "                rssE = rssError(yMat.A,yTest.A)\n",
    "                # 贪婪算法\n",
    "                if rssE < lowestError:\n",
    "                    lowestError = rssE\n",
    "                    wsMax = wsTest\n",
    "        ws = wsMax.copy()\n",
    "        returnMat[i,:]=ws.T\n",
    "    return returnMat"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.  ,  0.  ,  0.  , ...,  0.  ,  0.  ,  0.  ],\n",
       "       [ 0.  ,  0.  ,  0.  , ...,  0.  ,  0.  ,  0.  ],\n",
       "       [ 0.  ,  0.  ,  0.  , ...,  0.  ,  0.  ,  0.  ],\n",
       "       ...,\n",
       "       [ 0.05,  0.  ,  0.09, ..., -0.64,  0.  ,  0.36],\n",
       "       [ 0.04,  0.  ,  0.09, ..., -0.64,  0.  ,  0.36],\n",
       "       [ 0.05,  0.  ,  0.09, ..., -0.64,  0.  ,  0.36]])"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stageWise(abX, abY, 0.01, 200)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用更小的步长测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.   ,  0.   ,  0.   , ...,  0.   ,  0.   ,  0.   ],\n",
       "       [ 0.   ,  0.   ,  0.   , ...,  0.   ,  0.   ,  0.   ],\n",
       "       [ 0.   ,  0.   ,  0.   , ...,  0.   ,  0.   ,  0.   ],\n",
       "       ...,\n",
       "       [ 0.043, -0.011,  0.12 , ..., -0.963, -0.105,  0.187],\n",
       "       [ 0.044, -0.011,  0.12 , ..., -0.963, -0.105,  0.187],\n",
       "       [ 0.043, -0.011,  0.12 , ..., -0.963, -0.105,  0.187]])"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stageWise(abX, abY, 0.001, 5000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
